#!/usr/bin/env python
# -*- encoding: utf-8 -*-
'''
@File    :   evidence_generator.py    
@Contact :   raogx.vip@hotmail.com
@License :   (C)Copyright 2020

@Modify Time      @Author    @Version    @Desciption
------------      -------    --------    -----------
2021-02-15 17:54   WandongShi      1.0         None
'''
import torch.nn as nn
import torch
import numpy as np
import random
import copy
from utils import *
from load_pretrained_embedding import Glove

class evidence_generator:

    def __init__(self):
        self.input_file = r"/DataDisk_1/python_project/Myprojects/spert/data/Res14/graph/select_new_output_0_50_1.txt"

        self.aspect_rep = []
        self.opinion_rep = []
        self.pair_rep = []
        self.senti = []
        self.evidence = []
        self.mapidx = []
        self.ret = []
        self.sub_edges = 1

        self.construct_graph(self.input_file)

    def load_evidence(self, input_file):
        fp = open(input_file, 'r', encoding='utf-8')
        lines = fp.readlines()
        fp.close()
        pos_evi = []
        neg_evi = []
        neu_evi = []
        evidence_lines = []
        for line in lines:
            line = line.strip()
            data = line.split('\t')
            # print(data)
            at_term = data[1]
            ot_term = data[2]
            senti_class = data[3]
            if(senti_class == 'POS'):
                pos_evi.append((at_term, ot_term))
            elif(senti_class == 'NEG'):
                neg_evi.append((at_term, ot_term))
            else:
                neu_evi.append((at_term, ot_term))
        evidence_lines.append(pos_evi)
        evidence_lines.append(neg_evi)
        evidence_lines.append(neu_evi)
        self.evidence = evidence_lines

    def construct_graph(self, input_file):
        fp = open(input_file, 'r', encoding='utf-8')
        lines = fp.readlines()
        fp.close()
        mapidx = dict()
        mapidx['root'] = 0

        for line in lines:
            line = line.strip()
            data = line.split('\t')
            for ele in data:
                if ele not in mapidx.keys():
                    mapidx[ele] = len(mapidx)

        ele_len = len(mapidx)
        ret = np.zeros((ele_len, ele_len), dtype=np.float32)
        for line in lines:
            line = line.strip()
            data = line.split('\t')
            # print(data)
            self.aspect_rep.append(data[1])
            self.opinion_rep.append(data[2])
            self.senti.append(data[3])
            ret[0, mapidx[data[0]]] = 1
            ret[mapidx[data[0]], mapidx[data[1]]] = 1
            ret[mapidx[data[1]], mapidx[data[2]]] = 1
            ret[mapidx[data[2]], mapidx[data[3]]] = 1

        ret = ret + ret.T
        for i in range(ele_len):
            ret[i, i] = 1
        for edge in range(self.sub_edges):
            while(True):
                a = random.randint(0,ele_len-1)
                b = random.randint(0,ele_len-1)
                if(a!=b and ret[a][b]==1.0):
                    ret[a][b] = ret[b][a] = 0.0
                    copy_matrix = copy.deepcopy(ret)
                    if(self.is_graph(copy_matrix, ele_len)):
                        break;
                    ret[a][b] = ret[b][a] = 1.0

        ret = ret.reshape(1, ele_len, ele_len)
        self.mapidx = mapidx
        self.ret = ret


    def is_graph(self, ret, ele_len):
        for k in range(ele_len):
            for i in range(ele_len):
                if(ret[k][i] == 1.0):
                    for j in range(ele_len):
                        if(ret[i][k] == 1.0 and ret[k][j] == 1.0):
                            ret[i][j] = 1.0

        for i in range(ele_len):
            for j in range(ele_len):
                if(ret[i][j] + ret[j][i] == 0.0):
                    return False
        return True


    def get_aspect(self):
        return self.aspect_rep

    def get_opinion(self):
        return self.opinion_rep

    def get_senti(self):
        return self.senti

    def get_pairs(self):
        return self.pair_rep

    def get_evidence(self):
        return self.evidence

    def get_adj(self):
        return self.mapidx, self.ret